package com.hopu.v1.utils;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

/**
 * 二维码的工具类
 * @author fyh
 */
public class ZXingUtil {
    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

    /**
     * 加密：文字-->图片  将文本变成二维数组，
     * @param out: 输出流
     * @param format: 文件格式及后缀名
     * @param content
     * @throws WriterException
     * @throws IOException
     */
    public static void encodeimage(OutputStream out, String format, String content, int width, int height, String logo) throws WriterException, IOException {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.MARGIN, 1);

        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        int matrixWidth = bitMatrix.getWidth();

        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < matrixWidth; x++) {
            for (int y = 0; y < matrixWidth; y++) {
                img.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);
            }
        }

        if (logo != null) {
            img = logoImg(img, logo);
        }

        ImageIO.write(img, format, out);
    }

    /**
     * 解密，将生成的二维码转换成文字
     * @param file:二维码文件
     * @throws Exception
     */
    public static String decodeImage(File file) throws Exception {
        if (!file.exists()) {
            return "";
        }
        BufferedImage image = ImageIO.read(file);
        MultiFormatReader formatter = new MultiFormatReader();
        LuminanceSource source = new BufferedImageLuminanceSource(image);
        Binarizer binarizer = new HybridBinarizer(source);
        BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
        Result result = formatter.decode(binaryBitmap);
        System.out.println(result.getText());
        return result.getText();
    }

    /**
     * 传logo和二维码，生成-->带logo的二维码
     * @param matrixImage :二维码
     * @param logo ： 中间的logo
     * @return
     * @throws IOException
     */
    public static BufferedImage logoImg(BufferedImage matrixImage, String logo) throws IOException {
        Graphics2D g2 = matrixImage.createGraphics();
        BufferedImage logoImage = ImageIO.read(new File(logo));
        int height = matrixImage.getHeight();
        int width = matrixImage.getWidth();
        g2.drawImage(logoImage, width * 2 / 5, height * 2 / 5, width * 1 / 5, height * 1 / 5, null);

        BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setStroke(stroke);
        RoundRectangle2D.Float round = new RoundRectangle2D.Float(width * 2 / 5, height * 2 / 5, width * 1 / 5, height * 1 / 5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setColor(Color.WHITE);
        g2.draw(round);

        BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setStroke(stroke2);
        RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(width * 2 / 5 + 2, height * 2 / 5 + 2, width * 1 / 5 - 4, height * 1 / 5 - 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g2.setColor(Color.GRAY);
        g2.draw(round2);

        g2.dispose();
        matrixImage.flush();
        return matrixImage;
    }
}